package com.example.demo.util;

/**
 * @Author：zhoutaoming
 * @name：CAUtil
 * @Date：2023/11/22 14:53
 * @Version 1.0
 */
import sun.security.x509.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;

public class CASigningUtil {

    public static void main(String[] args) {
        try {
            // 生成密钥对
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();

            // 创建自签名证书
            X509Certificate selfSignedCert = generateSelfSignedCertificate(keyPair);

            // 保存私钥和证书到密钥库
            KeyStore keyStore = KeyStore.getInstance("JKS");
            char[] password = "keystorePassword".toCharArray();
            keyStore.load(null, password);
            keyStore.setKeyEntry("alias", keyPair.getPrivate(), password, new Certificate[]{selfSignedCert});

            // 保存密钥库到文件
            try (FileOutputStream fos = new FileOutputStream("keystore.jks")) {
                keyStore.store(fos, password);
            }

            System.out.println("CA签名成功，并且密钥库保存到keystore.jks文件中。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static X509Certificate generateSelfSignedCertificate(KeyPair keyPair) throws CertificateEncodingException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        // 创建证书的基本信息
        X509Certificate cert = null;
        try {
            X509CertInfo info = new X509CertInfo();
            Date from = new Date();
            Date to = new Date(from.getTime() + 365 * 24 * 60 * 60 * 1000L); // 有效期为一年

            CertificateValidity validity = new CertificateValidity(from, to);
            CertificateSerialNumber serialNumber = new CertificateSerialNumber(new java.util.Random().nextInt() & 0x7fffffff);

            X500Name owner = new X500Name("CN=CA, OU=Example, O=Example, L=City, ST=State, C=US");

            info.set(X509CertInfo.VALIDITY, validity);
            info.set(X509CertInfo.SERIAL_NUMBER, serialNumber);
            info.set(X509CertInfo.SUBJECT, owner);
            info.set(X509CertInfo.ISSUER, owner);
            info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
            info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));

            AlgorithmId algorithm = new AlgorithmId(AlgorithmId.sha256WithRSAEncryption_oid);
            info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithm));

            // 创建证书
            cert = new X509CertImpl(info);
            ((X509CertImpl) cert).sign(keyPair.getPrivate(), "SHA256withRSA");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            throw new RuntimeException(e);
        } catch (NoSuchProviderException e) {
            throw new RuntimeException(e);
        }
        return cert;
    }
}
